Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Add Rational RingSolver #2215

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

lemastero
Copy link
Contributor

@lemastero lemastero commented Nov 26, 2023

Changes

  • add Data.Rational.Tactic.RingSolver
  • example or Rational.RingSolver
  • add Data.Rational.Unnormalised.Tactic.RingSolver
  • example or Rational.Unnormalised.RingSolver
  • update CHANGELOG

Fix #1879

@MatthewDaggitt
Copy link
Contributor

Thanks, looks great! As you say if you could add some examples in README.Data.Rational(.Unnormalised) that would be awesome.

Comment on lines +34 to +38
f : (x : ℚ) → Maybe (0ℚ ≡ x)
f (mkℚ (pos 0) 0 _) = just refl
f (mkℚ (pos 0) (suc _) _) = nothing
f (mkℚ (pos (suc _)) _ _) = nothing
f (mkℚ (negsuc _) _ _) = nothing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be strongly tempted to lift this out as a definition in Data.Rational.Base, or else as a property (cf. Relation.Binary.WeaklyDecidable, for which we currently lack analogues at arity 0, 1) in Data.Rational.Properties.

Suggested name for such a refactored f: isZero-weakly-decidable?

That way, the imports for your solver modules then become very much simplified, in favour of those that are already currently used by the Rational.* modules...

... and there's (potentially) a downstream benefit in being able to reuse the definition of the corresponding Unnormalised function in the definition of this one.

Comment on lines +33 to +37
where
f : (x : ℚᵘ) → Maybe (0ℚᵘ ≃ x)
f (mkℚᵘ (pos zero) _) = just (*≡* refl)
f (mkℚᵘ (pos (suc _)) _) = nothing
f (mkℚᵘ (negsuc _) _) = nothing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.!

@jamesmckinna
Copy link
Contributor

jamesmckinna commented Nov 26, 2023

Re: refactoring suggestion

I think that it's possible that a 'better' approach is available via leveraging the construction in the (old) Algebra.RingSolver.Simple module: namely to turn a Decidable equality into a WeaklyDecidable one, and thereby define a 'smart' constructor for AlmostCommutativeRings.

Now, equality on Rational(.Unnormalised) is already proven Decidable (in *.Properties), so there might (even) be no need to define a separate f/isZero-weakly-decidable function at all.

@jamesmckinna
Copy link
Contributor

Re: refactoring (meta-comment)

I think there's a tension, especially as a new developer, between contributing a PR with as 'small' footprint as possible (which can have as a consequence a 'wide' collection of imports, and (lots of) local definitions), and refactoring it to distribute the various pieces over the library (as I suggested above). But I do think the latter is eventually the way to go, for the sake of leveraging the power already present in the library.

For the PR at hand: The definitions of the Solvers for Nat and Integer might be instructive in this regard, where the import interfaces/implementations are just about as minimal as you can get...

@lemastero lemastero changed the title Add Rational RingSolver WIP Add Rational RingSolver Nov 27, 2023
@lemastero
Copy link
Contributor Author

if you could add some examples in README.Data.Rational(.Unnormalised) that would be awesome.

There is clearly something wrong with RingSolvers in this PR. I defined very simple example here:

open import Data.Integer using (+_)
open import Data.Rational
open import Data.Rational.Properties

1/4 : ℚ
1/4 = + 1 / 4

3/4 : ℚ
3/4 = + 3 / 4

open import Relation.Binary.PropositionalEquality -- using (_≡_; refl)
open import Data.Rational.Tactic.RingSolver

lemma : ∀ x y → x + y + 1/4 + ½ ≃ 3/4 + y + x
lemma = {! solve-∀  !}

but this fails with:

Malformed call to solve.Expected target type to be like:  x y  x + y ≈ y + x.Instead: _19
when checking that the expression unquote solve-∀ has type _19

I think RingSolver does not like PropositionalEquality (but it does not like equality define in Rational.Properties either).

I will try to see if I can create example with existing SemiringSolver for begin with and do refactoring proposed, by @jamesmckinna.

@jamesmckinna
Copy link
Contributor

Ok, so this is clearly very troubling behaviour!
I'm not in fact myself any kind of expert on the various Solver implementations, so a shout-out to... hmm not sure...

@oisdk do you have any insight here to offer?

@gallais
Copy link
Member

gallais commented Nov 27, 2023

Given that the goal looks like a meta variable, it may be that the tactic is being
run too early. You may want to block on the meta so that you can wait for it to
be solved and then call the tactic once again.

Cf. the blockOnMeta call in this chunk of tactical I developed for #2033
and where I was facing similar issues.

@lemastero
Copy link
Contributor Author

I've found some resources on semigroup/ring solvers in Agda:

I will try to traverse the subject and fold it into better understanding - what is the problem here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Data.Rational.Tactic.RingSolver
4 participants